
interface FunctionalInterface{
  void onDraw();
}

int mousePressedTime = 0;
void setup() {
  size(300, 200);
}

void mousePressed(){
  mousePressedTime++;
  mousePressedTime = mousePressedTime % 256;
}
void draw(){
  background(255);
  smooth();
  switch(mousePressedTime%5){
    case 0:drawArc();break;
    case 1:drawCurve();break;
    case 2:drawSpline();break;
    case 3:drawSpline();break;
    default:drawContinuousBezierCurves();break;
  }
}

void drawArc(){
  rectMode(CENTER); // show bounding boxes
  stroke(128);
  rect(35, 35, 50, 50);
  rect(105, 35, 50, 50);
  rect(175, 35, 50, 50);
  rect(105, 105, 100, 50);

  stroke(0);
  arc(35, 35, 50, 50, 0, PI / 2.0); // lower quarter circle
  arc(105, 35, 50, 50, -PI, 0);  // upper half of circle
  arc(175, 35, 50, 50, -PI / 6, PI / 6); // 60 degrees
  arc(105, 105, 100, 50, PI / 2, 3 * PI / 2); // 180 degrees
}

void drawCurve()
{
  stroke(0);
  curve(40, 40, 80, 60, 100, 100, 60, 120);
  noStroke();
  fill(255, 0, 0);
  ellipse(40, 40, 3, 3);
  fill(0, 0, 255, 192);
  ellipse(100, 100, 3, 3);
  ellipse(80, 60, 3, 3);
  fill(255, 0, 0);
  ellipse(60, 120, 3, 3);
}

int[] coords = {
  40, 40, 80, 60, 100, 100, 60, 120, 50, 150
};



void drawSpline(){
  noFill();
  stroke(0);
  beginShape();
  curveVertex(40, 40); // the first control point
  curveVertex(40, 40); // is also the start point of curve
  curveVertex(80, 60);
  curveVertex(100, 100);
  curveVertex(60, 120);
  curveVertex(50, 150); // the last point of curve
  curveVertex(50, 150); // is also the last control point
  endShape();

  // Use the array to keep the code shorter;
  // you already know how to draw ellipses!
  fill(255, 0, 0);
  noStroke();
  for (int i = 0; i < coords.length; i += 2) {
    ellipse(coords[i], coords[i + 1], 3, 3);
  }
}

void drawBezierCurve(){
  ellipse(50, 75, 5, 5); // endpoints of curve
  ellipse(100, 75, 5, 5);
  fill(255, 0, 0);
  ellipse(25, 25, 5, 5);  // control points
  ellipse(125, 25, 5, 5);
  noFill();
  stroke(0);
  bezier(50, 75, 25, 25, 125, 25, 100, 75);
}

void drawContinuousBezierCurves()
{
  noFill();
  stroke(0);
   // Don't show where control points are
  switch(mousePressedTime%3){
   case 0:
   {
    
    beginShape();
    vertex(50, 75); // first point
    bezierVertex(25, 25, 125, 25, 100, 75);
    endShape();
    break;
   }
   case 1:
   {
    //2
    beginShape();
    vertex(30, 70); // first point
    bezierVertex(25, 25, 100, 50, 50, 100);
    bezierVertex(50, 140, 75, 140, 120, 120);
    endShape();
    break;
   }
   default:
   {
    //3
    beginShape();
    vertex(30, 70); // first point
    bezierVertex(25, 25, 100, 50, 50, 100);
    bezierVertex(20, 130, 75, 140, 120, 120);
    endShape();
    break;
   }
  }
}
